﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using Coticula.DTO;
using Coticula.Web.Models;

namespace Coticula.Web.Controllers
{
    public class ApiController : Controller
    {
        private readonly CoticulaDbContext _db = new CoticulaDbContext();

        private readonly ErrorMessage _errorMessage = new ErrorMessage
                                                {
                                                    Error = new ErrorMessage.ConctreteError
                                                                {
                                                                    Type = "Unauthorized",
                                                                    Message = "Tester is not authorized."
                                                                }
                                                };
        private bool CheckTesterUserAuthenticated()
        {
            return User.Identity.IsAuthenticated /*&& User.IsInRole("Tester")*/;
        }

        //
        // GET: /Api/Untested.json

        public ActionResult Untested(string format)
        {
            if (format != "json")
                return null;

            if (CheckTesterUserAuthenticated() == false)
            {
                return Json(_errorMessage, JsonRequestBehavior.AllowGet);
            }

            SpecificData.LastServerConnect = DateTime.Now;

            var untestedIdList = Solutions.UntestedId();
            return Json(untestedIdList, JsonRequestBehavior.AllowGet);
        }

        //
        // GET: /Api/Solution/5.json

        public ActionResult Solution(int id, string format)
        {
            if (format != "json")
                return null;

            if (CheckTesterUserAuthenticated() == false)
            {
                return Json(_errorMessage, JsonRequestBehavior.AllowGet);
            }

            var result = _db.Results.Include(r => r.Solution.Language).Single(r => r.Id == id);

            var solution = new Solution
            {
                Id = result.Id,
                Answer = result.Solution.Answer,
                LanguageId = result.Solution.LanguageId,
                ProblemId = result.Solution.ProblemId
            };

            return Json(solution, JsonRequestBehavior.AllowGet);
        }

        //
        // POST: /Api/Result.json

        [HttpPost]
        public ActionResult Result(Result result, string format)
        {
            if (format != "json")
                return null;

            if (CheckTesterUserAuthenticated() == false)
            {
                return Json(_errorMessage, JsonRequestBehavior.AllowGet);
            }

            if (ModelState.IsValid)
            {
                var res = _db.Results.Include(r => r.CompiledDetail).Include(r => r.Solution.Language).Single(r => r.Id == result.Id);
                res.VerdictId = result.VerdictId;
                res.Score = result.Score;

                CompiledDetails compiledDetails = null;
                if (res.CompiledDetailId != null && res.CompiledDetailId != 0)
                {
                    compiledDetails = _db.CompiledDetails.Single(r => r.Id == res.CompiledDetailId);
                    if (compiledDetails == null)
                    {
                        compiledDetails = new CompiledDetails();
                    }
                }
                else
                {
                    compiledDetails = new CompiledDetails();
                }
                compiledDetails.Output = result.CompileOutput.Trim();
                res.CompiledDetail = compiledDetails;

                try
                {
                    _db.Entry(res).State = EntityState.Modified;
                    _db.SaveChanges();
                    return Json("ok");
                }
                catch
                {

                }
            }
            return Json(new ErrorMessage
                            {
                                Error = new ErrorMessage.ConctreteError
                                            {
                                                Type = "Not valid",
                                                Message = "\"Result\" not valid."
                                            }
                            });
        }

        //
        // POST: /Api/ResultByTest.json

        [HttpPost]
        public ActionResult ResultByTest(ResultByTests result, string format)
        {
            if (format != "json")
                return null;

            if (CheckTesterUserAuthenticated() == false)
            {
                return Json(_errorMessage, JsonRequestBehavior.AllowGet);
            }

            if (ModelState.IsValid)
            {
                var res = _db.Results.Include(r => r.Solution).Where(r=>r.Id == result.Id).First();
                ICollection<TestsResults> testsResults = new Collection<TestsResults>();
                {
                    var testRes = _db.TestsResultses.Where(r => r.ResultId == result.Id);
                    foreach (var testsResultse in testRes)
                    {
                        _db.Entry(testsResultse).State = EntityState.Deleted;
                    }
                }
                for (int i = 0; i < result.Verdicts.Length; i++)
                {
                    testsResults.Add(new TestsResults{ResultId = result.Id, TestId = i+1, VerdictId = result.Verdicts[i]});
                }
                res.TestsResults = testsResults;
                try
                {
                    _db.Entry(res).State = EntityState.Modified;
                    _db.SaveChanges();
                    return Json("ok");
                }
                catch
                {
                }
            }
            return Json(new ErrorMessage
            {
                Error = new ErrorMessage.ConctreteError
                {
                    Type = "Not valid",
                    Message = "\"ResultByTests\" not valid."
                }
            });
        }

        //
        // GET: /Api/Signin.json

        [HttpPost]
        public ActionResult Signin(Login login, string format)
        {
            if (format != "json")
                return null;

            if (ModelState.IsValid)
            {
                try
                {
                    var logOnModel = new LogOnModel {Password = login.Password, UserName = login.User};
                    if (Membership.ValidateUser(logOnModel.UserName, logOnModel.Password))
                    {
                        FormsAuthentication.SetAuthCookie(logOnModel.UserName, logOnModel.RememberMe);
                        return Json("ok");
                    }
                    return Json(new ErrorMessage
                                    {
                                        Error = new ErrorMessage.ConctreteError
                                                    {
                                                        Type = "Login was unsuccessful",
                                                        Message = "The user name or password provided is incorrect."
                                                    }
                                    });
                }
                catch
                {

                }
            }
            return Json(new ErrorMessage
            {
                Error = new ErrorMessage.ConctreteError
                {
                    Type = "Not valid",
                    Message = "\"Login\" not valid."
                }
            });
        }
    }
}
